
module CPU where

import Graphics.UI.GLUT

-- Make
makeCPU :: Color4 GLfloat -> [Int] -> IO DisplayList
makeCPU  cor (mar:mdr:pc:mbr:sparc:lv:cpp:tos:opc:h:desl:[]) = do
	[listaCPU] <- genObjectNames 1
	defineList listaCPU Compile $ do
		-- Memory Addr Reg
		registrador "      MAR" (transforma mar) (Vector3 (-30) 40 10) cor
		-- Memory Data Reg
		registrador "      MDR" (transforma mdr) (Vector3 (-30) 30 10) cor
		-- PC
		registrador "      PC" (transforma pc) (Vector3 (-30) 20 10) cor
		-- MBR
		registrador "      MBR" ("","         " ++ pega8 0 (fromInt32 0 mbr)) (Vector3 (-30) 10 10) cor
		-- SPARC
		registrador "      SP" (transforma sparc) (Vector3 0 35 10) cor
		-- LV
		registrador "      LV" (transforma lv) (Vector3 0 25 10) cor
		-- CPP
		registrador "      CPP" (transforma cpp) (Vector3 0 15 10) cor
		-- TOS
		registrador "      TOS" (transforma tos) (Vector3 0 5 10) cor
		-- OPC
		registrador "      OPC" (transforma opc) (Vector3 0 (-5) 10) cor
		-- H
		registrador "       H" (transforma h) (Vector3 0 (-15) 10) cor
		-- Deslocador
		registrador "   Deslocador" (transforma desl) (Vector3 0 (-35) 10) cor
	shadeModel $= Flat
	return listaCPU
	
transforma :: Int -> (String, String)
transforma x = ((pega16 16 0 (fromInt32 0 x)),(pega16 0 0 (fromInt32 0 x)))

fromInt32 :: Int -> Int -> [Int]
fromInt32 32 _ = []
fromInt32 x valor = (mod valor 2) : fromInt32 (x + 1) (div valor 2)

pega16 :: Int -> Int -> [Int] -> String
pega16 _ 16 _ = []
pega16 ini x y = pega16 ini (x + 1) y ++ (if (x==7) then " " else "") ++ show (y!!(ini+x))

pega8 :: Int -> [Int] -> String
pega8 8 _ = []
pega8 x y = pega8 (x + 1) y ++ show (y!!x)

registrador :: String -> (String, String) -> Vector3 GLfloat -> Color4 GLfloat -> IO ()
registrador nome (valor1, valor2)  (Vector3 x y z) cor = do
	currentColor $= cor
	materialAmbient Front $= cor
	preservingMatrix $ do
		translate (Vector3 x y z :: Vector3 GLfloat)
		scale 4 1.3 (1::GLfloat)
		renderObject Solid (Cube 5)
	--lighting $= Disabled
	preservingMatrix $ do
		currentColor $= Color4 0 0 0 1		
		translate (Vector3 (x - 9) (y + 2) (z + 2.6) :: Vector3 GLfloat)			
		scale 0.01 0.01 (0.01::GLfloat)
		renderString MonoRoman nome
	preservingMatrix $ do
		translate (Vector3 (x - 9) (y - 1) (z + 2.6) :: Vector3 GLfloat)			
		scale 0.01 0.01 (0.01::GLfloat)
		renderString MonoRoman valor1
	preservingMatrix $ do
		translate (Vector3 (x - 9) (y - 3) (z + 2.6) :: Vector3 GLfloat)			
		scale 0.01 0.01 (0.01::GLfloat)
		renderString MonoRoman valor2
	--lighting $= Enabled	